From 66a8df749b23aadce9a74495c61b301c64f343d7 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Mon, 6 Jun 2005 20:18:09 +0000 Subject: [PATCH] bitkeeper revision 1.1662.1.13 (42a4af81MIF4vpJsgsYgQT--FGFI5w) channel.py, XendDomainInfo.py: Cleanup event channel code. Signed-off-by: Mike Wray Signed-off-by: Christian Limpach --- tools/python/xen/xend/XendDomainInfo.py | 56 +++++++++---- tools/python/xen/xend/server/channel.py | 104 ++++++++++++++++-------- 2 files changed, 113 insertions(+), 47 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index c466910d97..fc03dbf048 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -17,10 +17,10 @@ import xen.lowlevel.xc; xc = xen.lowlevel.xc.new() from xen.util.ip import check_subnet, get_current_ipgw from xen.util.blkif import blkdev_uname_to_file -from xen.xend.server import channel, controller +from xen.xend.server import controller from xen.xend.server import SrvDaemon; xend = SrvDaemon.instance() from xen.xend.server import messages -from xen.xend.server.channel import channelFactory +from xen.xend.server.channel import EventChannel, channelFactory from xen.xend import sxp from xen.xend.PrettyPrint import prettyprintstring @@ -242,7 +242,7 @@ class XendDomainInfo: self.channel = None self.store_channel = None - self.store_mfs = None + self.store_mfn = None self.controllers = {} self.info = None @@ -286,6 +286,9 @@ class XendDomainInfo: def getChannel(self): return self.channel + def getStoreChannel(self): + return self.store_channel + def update(self, info): """Update with info from xc.domain_getinfo(). """ @@ -401,6 +404,8 @@ class XendDomainInfo: if self.channel: sxpr.append(self.channel.sxpr()) + if self.store_channel: + sxpr.append(self.store_channel.sxpr()) console = self.getConsole() if console: sxpr.append(console.sxpr()) @@ -550,8 +555,16 @@ class XendDomainInfo: def destroy(self): """Completely destroy the vm. """ - self.cleanup() - self.destroy_domain() + try: + self.cleanup() + except Exception, ex: + log.warning("error in domain cleanup: %s", ex) + pass + try: + self.destroy_domain() + except Exception, ex: + log.warning("error in domain destroy: %s", ex) + pass def destroy_domain(self): """Destroy the vm's domain. @@ -559,8 +572,11 @@ class XendDomainInfo: devices have been released. """ if self.channel: - self.channel.close() - self.channel = None + try: + self.channel.close() + self.channel = None + except: + pass if self.image: try: self.image.destroy() @@ -617,20 +633,32 @@ class XendDomainInfo: if not self.restore: self.setdom(dom) - def create_channel(self): - """Create the control channel to the domain. - If saved info is available recreate the channel using the saved ports. + def openChannel(self, name, local, remote): + """Create a channel to the domain. + If saved info is available recreate the channel. + + @param local default local port + @param remote default remote port """ local = 0 remote = 1 if self.savedinfo: - info = sxp.child(self.savedinfo, "channel") + info = sxp.child(self.savedinfo, name) if info: local = int(sxp.child_value(info, "local_port", 0)) remote = int(sxp.child_value(info, "remote_port", 1)) - self.channel = channelFactory().openChannel(str(self.id), - local_port=local, - remote_port=remote) + chan = channelFactory().openChannel(self.id, local_port=local, + remote_port=remote) + return chan + + def eventChannel(self, name): + return EventChannel.interdomain(0, self.id) + + def create_channel(self): + """Create the channels to the domain. + """ + self.channel = self.openChannel("channel", 0, 1) + self.store_channel = self.eventChannel("store_channel") def create_configured_devices(self): devices = sxp.children(self.config, 'device') diff --git a/tools/python/xen/xend/server/channel.py b/tools/python/xen/xend/server/channel.py index e2b2043e66..e5b82b5330 100755 --- a/tools/python/xen/xend/server/channel.py +++ b/tools/python/xen/xend/server/channel.py @@ -14,52 +14,90 @@ DEBUG = 0 RESPONSE_TIMEOUT = 20.0 -def eventChannel(dom1, dom2): - """Create an event channel between domains. - The returned dict contains dom1, dom2, port1 and port2 on success. +class EventChannel(dict): + """An event channel between domains. + """ + + def interdomain(cls, dom1, dom2, port1=0, port2=0): + """Create an event channel between domains. + + @return EventChannel (None on error) + """ + v = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2, + port1=port1, port2=port2) + if v: + v = cls(dom1, dom2, v) + return v + + interdomain = classmethod(interdomain) + + def __init__(self, dom1, dom2, d): + d['dom1'] = dom1 + d['dom2'] = dom2 + self.update(d) + self.dom1 = dom1 + self.dom2 = dom2 + self.port1 = d.get('port1') + self.port2 = d.get('port2') + + def close(self): + """Close the event channel. + """ + def evtchn_close(dom, port): + try: + xc.evtchn_close(dom=dom, port=port) + except Exception, ex: + pass + + if DEBUG: + print 'EventChannel>close>', self + evtchn_close(self.dom1, self.port1) + evtchn_close(self.dom2, self.port2) + + def sxpr(self): + return ['event-channel', + ['dom1', self.dom1 ], + ['port1', self.port1 ], + ['dom2', self.dom2 ], + ['port2', self.port2 ] + ] - @return dict (empty on error) + def __repr__(self): + return ("" + % (self.dom1, self.port1, self.dom2, self.port2)) + +def eventChannel(dom1, dom2, port1=0, port2=0): + """Create an event channel between domains. + + @return EventChannel (None on error) """ - evtchn = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2) - if evtchn: - evtchn['dom1'] = dom1 - evtchn['dom2'] = dom2 - return evtchn + return EventChannel.interdomain(dom1, dom2, port1=port1, port2=port2) def eventChannelClose(evtchn): - """Close an event channel that was opened by eventChannel(). + """Close an event channel. """ - def evtchn_close(dom, port): - if (dom is None) or (port is None): return - try: - xc.evtchn_close(dom=dom, port=port) - except Exception, ex: - pass - if not evtchn: return - if DEBUG: - print 'eventChannelClose>', evtchn - evtchn_close(evtchn.get('dom1'), evtchn.get('port1')) - evtchn_close(evtchn.get('dom2'), evtchn.get('port2')) - + evtchn.close() class ChannelFactory: - """Factory for creating channels. + """Factory for creating control channels. Maintains a table of channels. """ """ Channels indexed by index. """ - channels = {} + channels = None thread = None notifier = None """Map of ports to the virq they signal.""" - virqPorts = {} + virqPorts = None def __init__(self): """Constructor - do not use. Use the channelFactory function.""" + self.channels = {} + self.virqPorts = {} self.notifier = xu.notifier() # Register interest in virqs. self.bind_virq(xen.lowlevel.xc.VIRQ_DOM_EXC) @@ -70,10 +108,6 @@ class ChannelFactory: self.virqPorts[port] = virq log.info("Virq %s on port %s", virq, port) - def virq(self): - log.error("virq") - self.notifier.virq_send(self.virqPort) - def start(self): """Fork a thread to read messages. """ @@ -182,9 +216,13 @@ class ChannelFactory: return None def openChannel(self, dom, local_port=0, remote_port=0): - return (self.findChannel(dom, local_port=local_port, remote_port=remote_port) - or - self.newChannel(dom, local_port, remote_port)) + chan = self.findChannel(dom, local_port=local_port, + remote_port=remote_port) + if chan: + return chan + chan = self.newChannel(dom, local_port, remote_port) + return chan + def createPort(self, dom, local_port=0, remote_port=0): """Create a port for a channel to the given domain. @@ -218,7 +256,7 @@ def channelFactory(): return inst class Channel: - """Chanel to a domain. + """Control channel to a domain. Maintains a list of device handlers to dispatch requests to, based on the request type. """ -- 2.30.2